/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package estructurassa.expertos;

import estructurassa.entidades.ClasificacionProducto;
import estructurassa.entidades.CodificacionBrisch;
import estructurassa.entidades.Pieza;
import estructurassa.expertos.excepciones.ABMClasificacionProductoException;
import estructurassa.expertos.excepciones.ABMProductoTerminadoException;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import newotcapp.modeloComboBox.ItemComboGenerico;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import persistencia.Conexion;
import persistencia.Fachada;
import persistencia.exceptions.ExcepcionFachada;

/**
 *
 * @author diego
 */
public class ExpertoABMClasificacionProducto implements Experto {

    public void guardar(ClasificacionProducto clasificacion) throws ABMProductoTerminadoException, ExcepcionFachada {
        validarClasificacion(clasificacion);
        validarExistenciaClasificacion(clasificacion);
        ExpertoCodigo expertoCodigo = (ExpertoCodigo) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.GENERAR_CODIGO);
        clasificacion.setCodigo(expertoCodigo.generarCodigo(clasificacion));
        if (clasificacion.getId() == null) {
            clasificacion.setUltimoIngresado(0);
        }
        clasificacion.setVigente(true);
        try {
            Conexion.getInstancia().iniciarTX();
            Fachada.getInstancia().guardar(clasificacion);
            Conexion.getInstancia().confirmarTx();
        } catch (ExcepcionFachada ex) {
            Conexion.getInstancia().deshacerTx();
            throw ex;
        }
    }

    private void validarClasificacion(ClasificacionProducto clasificacion) throws ABMProductoTerminadoException {
        if (clasificacion.getNombre().length() == 0) {
            throw new ABMProductoTerminadoException("Debe ingresar Nombre Clasificación");
        }
    }

    private void validarExistenciaClasificacion(ClasificacionProducto clasificacion) throws ABMProductoTerminadoException {
        Criteria nombreClasificacion = Fachada.getInstancia().crearCriterio(ClasificacionProducto.class).add(Restrictions.eq("nombre", clasificacion.getNombre()).ignoreCase());
        nombreClasificacion.add(Restrictions.eq("vigente", true));
        if (!Fachada.getInstancia().buscar(ClasificacionProducto.class, nombreClasificacion).isEmpty()) {
            throw new ABMProductoTerminadoException("La clasificación: " + clasificacion.getNombre() + " ya existe.");
        }
    }

    public void darBaja(ClasificacionProducto clasificacionProductoTerminado) throws ABMClasificacionProductoException, ExcepcionFachada {
        String inicioCodigo = clasificacionProductoTerminado.getCodigo().substring(0, 5);
        Criteria codigoProducto = Fachada.getInstancia().crearCriterio(Pieza.class);
        codigoProducto.add(Restrictions.like("codigo", inicioCodigo + "%"));
        if (!Fachada.getInstancia().buscar(Pieza.class, codigoProducto).isEmpty()) {
            throw new ABMClasificacionProductoException("Hay productos que pertenencen a la clasificación: " + clasificacionProductoTerminado.getNombre() + ". Imposible eliminar.");
        }
        clasificacionProductoTerminado.setVigente(false);
        Fachada.getInstancia().guardar(clasificacionProductoTerminado);
    }
    
    public List buscarClasificacionesProductos(String codigoTipo) {
        Criteria vigente = Fachada.getInstancia().crearCriterio(ClasificacionProducto.class).add(Restrictions.eq("vigente", true));
        vigente.createCriteria("categoriaBrisch").add(Restrictions.eq("codigo", codigoTipo));
        return Fachada.getInstancia().buscar(ClasificacionProducto.class, vigente);
    }

    public List buscarTipoProductos(String codigoTipo) {
        Criteria criterio = Fachada.getInstancia().crearCriterio(CodificacionBrisch.class);
        criterio.add(Restrictions.eq("codigo", codigoTipo));
        return Fachada.getInstancia().buscar(CodificacionBrisch.class, criterio);
    }
}
